<?php

namespace App\Http\Controllers\Common;

use App\Mail\OrderShipped;
use App\Models\Article\ArticleOrder;
use App\Models\Constant\Constant;
use App\Models\Constant\FileConstant;
use App\Models\Constant\UploadConstant;
use App\Models\Setting\SysSetting;
use App\Models\User\Favorite;
use App\Models\User\MemberOrder;
use App\Models\User\User;
use EasyWeChat\Factory;
use Illuminate\Http\Request;
use App\Models\Article\ArticleClassify;
use App\Models\Article\ArticleInfo;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Str;

abstract class ApiController extends CommonController {

    public function email(Request $request){
        $token = $request->header('token');
        $email = $request->input('email');
        $articleId = $request->input('articleId');
        $id = checkJWT($token)['id'];
        $user = User::where(compact('id'))->first();

        if(empty($user))return responseFail('未找到有效用户！');

        if(empty($user->email)){
            $user->email = $email;
            $user->save();
        }
        Mail::to($email)->send(new OrderShipped($articleId));
        return responseSuccess();
    }


    /**
     * 首页
     * @param Request $request
     * @Date 2022/11/12 23:27
     * @Author Rudy
     * @return \Illuminate\Http\JsonResponse
     */
    public function index(Request $request) {
        $from = $request->header('from');
        $isMember = false;
        $user= [];
        if($request->hasHeader('token')){
            $token = $request->header('token');
            $id = checkJWT($token)['id'];
            $user = User::where(compact('id'))->first(['avatar','nick_name','is_member','expire_time']);
            if(empty($user)){
                Log::error('这个token没有查找到对象！'.$token);
            }else{
                $isMember = $user->is_member==1;
                $user = $user->toArray();

            }

        }

        /*********************************** 分类 *******************************************************/
        $classifies = $this->getArticleClassifies($from);

        $article = new ArticleInfo();
        //置顶的三篇教程
        $topRecords = $article->getTopRecords();

        //热词搜索
        $hotWords = $article->getHotWords($from);

        $notice = ['为答谢新老顾客，特推出优惠活动！除首试会员外，会员期内提前购买任何类型会员，享受8.5折优惠！'];

        //总文章数
        $total = $article->getArticleCount();

        //今日更新文章数
        $todayCount = $article->getTodayUpdateCount($from);

        //获取首页的12个ppt
        $pptRecords = $article->getPptRecords(12);

        //获取今日更新的文章
        $todayRecords = $article->getTodayRecords(24);
        $allTodayRecords = $todayRecords['allTodayRecords'];
        $limitTodayRecords = $todayRecords['limitTodayRecords'];
        return responseSuccess([],0,100000,compact('limitTodayRecords','allTodayRecords','pptRecords','topRecords','classifies','user','total','hotWords','notice','todayCount'));
    }

    /**
     * 搜索
     * @param Request $request
     * @Date 2023/3/28 14:37
     * @Author Rudy
     * @return \Illuminate\Http\JsonResponse
     */
    public function lst(Request $request) {

        $isMember = false;
        if($request->hasHeader('token')){
            $token = $request->header('token');
            $id = checkJWT($token)['id'];
            $user = User::where('id',$id)->first(['id','avatar','nick_name','is_member','expire_time','ex_is_member']);
            $isMember = $user->is_member==1 || $user->ex_is_member==1;
        }
        $from = $request->header('from');
        $page = $request->input('page',1);
        $pageSize = $request->input('pageSize',30);
        $title = $request->input('title');
        $isToday = $request->input('isToday',2);
        $pos = $request->input('pos',0);
        if($pos==2 && Str::contains($title, '教育整顿')){
            $title  = '纪%教育整顿';
        }

        $classifyId = $request->input('classifyId',UploadConstant::CLASSIFY_ID_ALL);

        /*
         * 36:述责述廉述德
         * 84:述职述责述法
         *
         * 2025-11-17，模仿如来网升级文章分类时，分类36和48合并为一个
         * */

        if(in_array($classifyId,[36,84])){
            $classifyId = [36,84];
        }else{
            //判断是父类还是子类
            $childrenClassifyId = ArticleClassify::where('pid',$classifyId)->get(['id']);
            if($childrenClassifyId->count()>0){
                $classifyId = $childrenClassifyId->toArray();
            }
        }
        $conditions = compact('title','classifyId');
        $cols = ['id','title','see_num','download_num','created_at','type','publish_at'];
        $records = (new ArticleInfo())->getLst($conditions);
        if(!$isMember){
            //$records = $records->where('is_sensitive',2);
        }
        if($isToday==1){
            $pageSize = 900;
            $records = $records->whereDate('publish_at', date('Y-m-d'));
        }

        if($from==Constant::FROM_CODE){
            $records = $records->where('type', 'docx');
        }

        $records = $records->where('publish_at','<=',date('Y-m-d H:i:s'))->paginate($pageSize,$cols,'page',$page);
        foreach ($records as $record) {
            $record->human_time = date('m-d',strtotime($record->publish_at));
        }

        $pptRecords = ArticleInfo::query()->where('type','pptx')->orderByDesc('id')->limit(12)->get()->each(function ($item) {
            $item->publish_at = date('m-d',strtotime($item->publish_at));
        });


        return responseSuccess($records->items(),$records->total(),100000,[
            'pptRecords'=>$pptRecords->toArray()??[],
        ]);
    }

    public function detail(Request $request) {
        $this->validate($request, ['id'=>'required'],[],['id'=>'文章ID']);
        $from = $request->header('from');
        $user = null;
        if($request->hasHeader('token')){
            $token = $request->header('token');
            $id = checkJWT($token)['id'];
            $user = User::where(compact('id'))->first();
        }
        $classifies = $this->getArticleClassifies($from);

        /*if($from==Constant::FROM_CODE){
            foreach ($classifies as $k=>$item){
                if(Str::contains($item->title,'PPT'))
                    unset($classifies[$k]);
            }
        }*/

        $id = $request->input('id');
        $record = ArticleInfo::where(compact('id'))->first();
        if(empty($record))return responseFail('未查到有效记录！');

        //如果是敏感文章，没有登录或者不是会员，则不能看到该文章
        if($record->is_sensitive==1){
            if(empty($user) || ($user->is_member!=1 && $user->ex_is_member!=1)){
                //return responseFail('未查到有效记录！');
            }

        }

        //收藏
        $record->is_favorite = $record->isFavoriteByUserId($user->id??0)?1:2;

        //用户是空，或者 既不是主会员也不是副会员
        if(empty($user) || ($user->is_member!=1 && $user->ex_is_member!=1)){
            $record->content = $record->summary;
        }

        $record->increment('see_num');

        //上一篇
        $cols = ['id','title','type','created_at'];
        $previousPostID = ArticleInfo::where('id', '<', $id)->max('id');
        $before = ArticleInfo::where(['id'=>$previousPostID])->first($cols);

        $nextPostId = ArticleInfo::where('id', '>', $id)->min('id');
        $next = ArticleInfo::where(['id'=>$nextPostId])->first($cols);
        if(empty($next)){
            $next = $before;
        }

        //最新发布
        $last = ArticleInfo::query();
        if(empty($user) || ($user->is_member!=1 && $user->ex_is_member!=1)){
            //$last = $last->where('is_sensitive',2);
        }
        $last = $last->take(10)->orderByDesc('id')->get(['id','title','type']);
        foreach ($last as &$item) {
            $item->icon = $item->type==FileConstant::FILE_TYPE_DOCX?asset('common/img/word.png'):
                asset('common/img/ppt.png');
        }
        $record->is_show_download = false;

        if(empty($user)){
            $record->is_show_download = false;
        }else{
            if($user->is_member==1 || $user->ex_is_member==1 || $user->isBuyArticle($record->id)){
                $record->is_show_download = true;
                //添加浏览记录
                $user->addSeeLog($record->id,Constant::SEE_LOG_TYPE_SEE);

            }
        }
        //如果是免费专区的
        if(in_array($record->classify_id,[FileConstant::CLASSIFY_ID_FREE])){
            $record->is_show_download = true;
        }
        unset($record->summary);
        return responseSuccess($record->toArray(),1,100000,compact('user','before','next','last','classifies'));
    }

    public function showMemberType(Request $request) {
        $user= null;
        if($request->hasHeader('token')){
            $token = $request->header('token');
            $id = checkJWT($token)['id'];
            $user = User::where(compact('id'))->first(['id','avatar','nick_name','is_member','expire_time']);
        }

        $memberType = ['first','month','quarter','year'];
        if(!empty($user) && $user->isBuyFirst()){
            unset($memberType[0]);
        }
        $map_type = SysSetting::whereIn('key',$memberType)->get(['id','key','val as stand_price','item_desc as title']);
        foreach ($map_type as $item) {
            $item->price = $item->stand_price;
            if(!empty($user) && $user->is_member==1 && date('Y-m-d H:i:s')<$user->expire_time){
                $item->btn = '续费';
                if($item->key!='first')
                    $item->price = round($item->stand_price*Constant::DISCOUNT,2);
            }else{
                $item->btn = '立即开通';
            }

            if($item->key=='first'){$item->during = '30天';$item->desc = '首次试用';};
            if($item->key=='month'){$item->during = '一个月';$item->desc = '短期服务';};
            if($item->key=='quarter'){$item->during = '一个季度';$item->desc = '经济实惠';};
            if($item->key=='year'){$item->during = '一年';$item->desc = '超高性价比';};
        }
        return responseSuccess(compact('map_type','user'));
    }

    public function exShowMemberType(Request $request) {
        $user= null;
        if($request->hasHeader('token')){
            $token = $request->header('token');
            $id = checkJWT($token)['id'];
            $user = User::where(compact('id'))->first(['id','avatar','nick_name','ex_is_member','ex_expire_time']);
        }

        $memberType = ['exfirst','exmonth','exquarter','exyear'];
        if(!empty($user) && $user->isExBuyFirst()){
            unset($memberType[0]);
        }
        $map_type = SysSetting::whereIn('key',$memberType)->get(['id','key','val as stand_price','item_desc as title']);
        foreach ($map_type as $item) {
            $item->price = $item->stand_price;
            $item->btn = '立即开通';
            /*if(!empty($user) && $user->is_member==1 && time()<$user->expire_time){
                $item->btn = '续费';
                if($item->key!='first')
                    $item->price = round($item->stand_price*0.85,2);
            }else{
                $item->btn = '立即开通';
            }*/

            if($item->key=='exfirst'){$item->during = Constant::ExFirstDay.'天';$item->desc = '首次试用';};
            if($item->key=='exmonth'){$item->during = '一个月';$item->desc = '短期服务';};
            if($item->key=='exquarter'){$item->during = '一个季度';$item->desc = '经济实惠';};
            if($item->key=='exyear'){$item->during = '一年';$item->desc = '超高性价比';};
        }
        return responseSuccess(compact('map_type','user'));
    }

    public function userInfo(Request $request) {
        $token = $request->header('token');
        $id = checkJWT($token)['id'];
        $user = User::where(compact('id'))->first();

        if(empty($user))return responseFail('未找到有效用户！');

        $mapMemberType = $this->getMemberType();
        if($user->is_member==1){
            //$type = $user->getMemberType()->type??'';
            $type = $user->type;
            $user->member_type = $type;
            $user->member_type_name = $mapMemberType[$type]??'普通用户';
        }else{
            //$user->member_type = 0;
            $user->member_type = 'normal';
            $user->member_type_name = '普通用户';
        }
        $user->expire_days = 0;
        if($user->expire_time>date('Y-m-d H:i:s')){
            $user->expire_days = Carbon::parse($user->expire_time)->diffInDays(Carbon::now())+1;
        }
        return responseSuccess($user->toArray());
    }
    public function exuserInfo(Request $request) {
        $token = $request->header('token');
        $id = checkJWT($token)['id'];
        $user = User::where(compact('id'))->first();

        if(empty($user))return responseFail('未找到有效用户！');

        $mapMemberType = $this->getExMemberType();
        if($user->ex_is_member==1){
            //$type = $user->getMemberType()->type??'';
            $type = $user->ex_type;
            $user->member_type = $type;
            $user->member_type_name = $mapMemberType[$type]??'普通用户';
        }else{
            //$user->member_type = 0;
            $user->member_type = 'normal';
            $user->member_type_name = '普通用户';
        }
        $user->expire_days = 0;
        if($user->ex_expire_time>date('Y-m-d H:i:s')){
            $user->expire_days = Carbon::parse($user->ex_expire_time)->diffInDays(Carbon::now())+1;
        }
        return responseSuccess($user->toArray());
    }


    public function exportFile(Request $request) {
        $id = $request->input('id');
        $downloadType = $request->input('downloadType');
        $this->validate($request, ['id'=>'required','downloadType'=>'required']);

        $record = ArticleInfo::where(compact('id'))->first();
        if(empty($record)){return responseFail('文件为空！');}


        //如果源记录是 ppt
        //Log::info('record->type',[$record->type]);
        if(in_array($record->type, [FileConstant::FILE_TYPE_PPT,FileConstant::FILE_TYPE_PPTX])){
            //Log::info('downloadType',[$downloadType]);
            $fileUlr = in_array($downloadType, [FileConstant::FILE_TYPE_DOCX,FileConstant::FILE_TYPE_DOC,'word'])?$record->docx_url:$record->file_url;
        }else{
            $fileUlr = $record->file_url;
        }
        $ext = Str::after($fileUlr, '.');
        $name = Str::before($record->title, '.');
        //如果是免费专区
        if(in_array($record->classify_id,[FileConstant::CLASSIFY_ID_FREE])){
            return response()->download(public_path($record->file_url),$name.'.'.$ext);
        }

        //如果不是免费的
        $token = $request->header('token')??$request->input('token');
        $id = checkJWT($token)['id'];
        //$id = 3;
        $user = User::where(compact('id'))->first();
        if(empty($user))return responseFail('未找到有效用户！');
        //if($user->is_member==2)return responseFail('对不起，您不是会员！');

        try {
            DB::beginTransaction();

            //计算下载数量
            //如果下载的是ppt，需要计数
            if(in_array($downloadType, [FileConstant::FILE_TYPE_PPT,FileConstant::FILE_TYPE_PPTX])){

                if($user->isMoreThanDownloadForPPT()){
                    //return responseFail('亲，今天的下载已满！明天再来下载哦！');
                }
                //UserDownloadLog::updateOrCreate(['user_id'=>$user->id,'article_id'=>$record->id,'article_type'=>'pptx']);
                $record->increment('download_num');
                $user->increment('download_ppt');
            }

            //如果下载的是doc/docx，但是文件类型也是doc/docx，说明是确实是下载doc，也需要计数
            if(in_array($downloadType, [FileConstant::FILE_TYPE_DOC,FileConstant::FILE_TYPE_DOCX]) &&
                in_array($record->type, [FileConstant::FILE_TYPE_DOC,FileConstant::FILE_TYPE_DOCX])){
                if($user->isMoreThanDownloadForDocx()){
                    //return responseFail('亲，今天的下载已满！明天再来下载哦！');
                }
                //UserDownloadLog::updateOrCreate(['user_id'=>$user->id,'article_id'=>$record->id,'article_type'=>'docx']);
                $record->increment('download_num');
                $user->increment('download_word');
                //添加下载记录
                $user->addSeeLog($record->id,Constant::SEE_LOG_TYPE_DOWNLOAD);
            }

            DB::commit();
            return response()->download(public_path($fileUlr),$name.'.'.$ext);
        }catch (\Exception $e){
            DB::rollBack();
            $tip = $e->getFile().':'.$e->getLine().':'.$e->getMessage();
            return responseFail($tip);
        }
    }

    public function exportZip(Request $request){

        ini_set('memory_limit', '1024M');

        $title = $request->input('title');
        $isToday = $request->input('isToday',2);
        $pos = $request->input('pos',0);
        if($pos==2 && Str::contains($title, '教育整顿')){
            $title  = '纪%教育整顿';
        }
        $pic = $request->input('pic',0);
        $classifyId = $request->input('classifyId',UploadConstant::CLASSIFY_ID_ALL);
        //判断是父类还是子类
        $childrenClassifyId = ArticleClassify::where('pid',$classifyId)->get(['id']);
        if($childrenClassifyId->count()>0){
            $classifyId = $childrenClassifyId->toArray();
        }

        //$conditions = compact('title','classifyId');
        $conditions = compact('title');
//        $conditions['orderBy']['col'] = 'sort';
//        $conditions['orderBy']['sort'] = 'desc';
        //Log::info('condtions',$conditions);


        $day = Carbon::parse('-12 months')->toDateString();

        $articleIds = (new ArticleInfo())->getLst($conditions)->where('type','!=','pptx')
            ->whereDate('created_at', '>=',$day)
            ->take(200)
            ->orderByDesc('id')
            ->pluck('id')->toArray();
        if(count($articleIds)<=0){
            return responseFail("不好意思，一键下载只能下载最近半年的文章！");
        }

        //Log::info('articleIds',$articleIds);
        $zipName= uniqid().'.zip';
        $zip = new \ZipArchive();
        $zipFileAbsPath = public_path('fileZip/'.$zipName);
        if(!is_dir($zipFileAbsPath)){
            //mkdir($zipFileAbsPath,0777,true);
        }
        $zip->open($zipFileAbsPath,\ZipArchive::CREATE);   //打开压缩包

        $records = ArticleInfo::whereIn('id',$articleIds)->get();
        foreach ($records as $record) {
            if(in_array($record->type, [FileConstant::FILE_TYPE_PPT,FileConstant::FILE_TYPE_PPTX])){
                $absPath = public_path($record->file_url);
                //$zip->addFile($absPath,basename($absPath));
                $basename = Str::beforeLast($record->title, '.');
                if(file_exists($absPath)){
                    //Log::info('ppt fileUrl:'.$absPath);
                    $zip->addFile($absPath,$basename.'.pptx');
                }else{
                    //Log::error('文件不存在:'.$absPath);
                }

                if(!empty($record->docx_url)){
                    //Log::info('ppt docx_url:'.$absPath);
                    $absPath = public_path($record->docx_url);
                    //$zip->addFile($absPath,basename($absPath));
                    if(file_exists($absPath)){
                        $zip->addFile($absPath,$basename.'.docx');
                    }else{
                        //Log::error('文件不存在:'.$absPath);
                    }
                }
            }else{
                $absPath = public_path($record->file_url);
                //$zip->addFile($absPath,basename($absPath));
                if(file_exists($absPath)){
                    $zip->addFile($absPath,$record->title);
                }else{
                    //Log::error('文件不存在:'.$absPath);
                }
            }
        }
        $zip->close();

        return response()->download($zipFileAbsPath);
    }

    public function queryOrder(Request $request) {
        $orderNumber = $request->input('orderNumber');
        $type = $request->input('type','member');
        if($type=='member'){
            $records = MemberOrder::where(['order_number'=>$orderNumber])->get();
        }else{
            $records = ArticleOrder::where(['order_number'=>$orderNumber])->get();
        }
        return responseSuccess($records->toArray(),1);
    }

    public function wxConfig(Request $request) {
        $url = $request->input('url');
        $config = config('wechat.default');
        $app = Factory::officialAccount($config);
        $wxConfig = $app->jssdk
            ->setUrl($url)
            ->buildConfig([
            'updateAppMessageShareData',
            'updateTimelineShareData',
            'onMenuShareTimeline',
            'onMenuShareAppMessage',
            'onMenuShareWeibo',
            'onMenuShareQZone'
        ], $debug = true, $beta = false, $json = true);

        return responseSuccess(compact('wxConfig'));
    }

    public function favorite(Request$request) {
        $token = $request->header('token');
        $user_id = checkJWT($token)['id'];
        $action = $request->input('action');
        $article_id = $request->input('article_id');

        $this->validate($request, [
            'action'=>'required',
            'article_id'=>'required',
        ]);

        if($action==1){
            Favorite::query()->updateOrCreate(compact('user_id','article_id'),compact('user_id','article_id'));
        }else{
            Favorite::query()->where(compact('user_id','article_id'))->forceDelete();
        }
        return responseSuccess();
    }

    public function favoriteLst(Request $request) {
        $userId = $request->input('userId');
        $page = $request->input('page',1);
        $pageSize = $request->input('pageSize',90);
        $records = Favorite::query()->where('user_id',$userId)->orderBy('id','desc')
            ->with('getArticle:id,title,type')
            ->paginate($pageSize,['*'],'page',$page);
        return responseSuccess($records->items(),$records->total());
    }



}
